<template>
  <h2>计算属性</h2>
  <div class="note">
    <p>1. 推荐使用计算属性来描述依赖响应式状态的复杂逻辑</p>
    <p>2. 计算属性 ref 会在模板中自动解包，因此在模板表达式中引用时无需添加 .value。</p>
    <p>
      3. 计算属性值会基于其响应式依赖被缓存,
      故只要值不改变，访问多少次都会立即返回先前的计算结果，而不用重复执行 getter 函数
    </p>
    <p>4. 计算属性默认是只读的,如果想要可写，可以通过同时提供 getter 和 setter 来创建</p>
  </div>

  <hr class="hr-style" />
  <h3>计算属性的基本用法</h3>
  <div>
    <div>{{ publishedBooksMessage }}</div>
  </div>

  <hr class="hr-style" />
  <h3>可写计算属性</h3>
  <div>
    <div>{{ fullname }}</div>
    <!-- 模板表达式 不能用来执行赋值操作，只能用来显示数据。如下写法会使初始名字与修改名字显示相同<div>修改名字：{{ fullname = 'John Doe'  }}</div> -->
    <!-- <div>修改名字：{{ fullname = 'Lucy Doe'  }}</div> -->
    <button @click="changeName">点击修改名字</button>
  </div>

  <hr class="hr-style" />
  <h2>注意事项</h2>
  <div class="note">
    <p>1. Getter 不应有副作用:getter 的职责应该仅为计算和返回该值,不要改变其他状态、在 getter 中做异步请求或者更改 DOM！</p>
    <p>2. 避免直接修改计算属性值:计算属性的返回值应该被视为只读的，并且永远不应该被更改</p>
  </div>

</template>

<script lang="ts">
export default {
  name: 'Study3StuDemo3'
}
</script>

<script setup lang="ts">
import { computed, reactive, ref } from 'vue'

const author = reactive({
  name: 'Json',
  books: ['Vue 2 - Advanced Guide', 'Vue 3 - Basic Guide', 'Vue 4 - The Mystery']
})
const publishedBooksMessage = computed(() => {
  return author.books.length > 0
    ? `Author ${author.name} has published ${author.books.length} books.`
    : 'No books published yet.'
})

const firstname = ref('John')
const lastname = ref('Doe')
const fullname = computed({
  get() {
    return firstname.value + ' ' + lastname.value
  },
  set(newFullname) {
    ;[firstname.value, lastname.value] = newFullname.split(' ')
  }
})
function changeName() {
  fullname.value = 'Lucy Doe'
  return fullname.value
}
</script>

<style scoped>
body {
  padding: 20px;
}
h2 {
  color: red;
}
h3 {
  color: rgb(220, 85, 85);
}
.hr-style {
  border: 3px solid gold;
  margin: 20px 0;
}
.note {
  margin: 10px;
  padding: 10px;
  border: 3px solid rgb(221, 121, 202);
}
.note p {
  color: rgb(226, 106, 204);
  font-weight: bold;
}
</style>
